home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Freelog 125
/
Freelog_MarsAvril2015_No125.iso
/
Musique
/
Quod Libet
/
quodlibet-3.3.0-installer.exe
/
bin
/
quodlibet
/
formats
/
midi.pyc
(
.txt
)
< prev
next >
Wrap
Python Compiled Bytecode
|
2014-12-31
|
5KB
|
172 lines
# Source Generated with Decompyle++
# File: in.pyc (Python 2.7)
import struct
from quodlibet.formats._audio import AudioFile
class MidiError(Exception):
pass
class MidiFile(AudioFile):
format = 'MIDI'
mimes = [
'audio/midi',
'audio/x-midi']
def __init__(self, filename):
h = open(filename, 'rb')
try:
if h.read(4) != 'MThd':
raise MidiError('Not a Midi file')
h.seek(0, 0)
try:
self['~#length'] = read_midi_length(h)
except Exception:
pass
finally:
h.close()
self.sanitize(filename)
def write(self):
pass
def reload(self, *args):
title = self.get('title')
super(MidiFile, self).reload(*args)
if title is not None:
self.setdefault('title', title)
def can_change(self, k = None):
if k is None:
return [
'title']
return None == 'title'
info = MidiFile
types = [
MidiFile]
extensions = [
'.mid']
(TEMPO, MIDI) = range(2)
def var_int(string):
val = 0
i = 0
while None:
x = ord(string[i])
i += 1
val = (val << 7) + (x & 127)
if not x & 128:
return (val, i)
return None
def read_track(chunk):
'''Retuns a list of midi events and tempo change events'''
tempos = []
events = []
deltasum = 0
status = ''
while chunk:
(delta, i) = var_int(chunk)
deltasum += delta
chunk = chunk[i:]
event_type = chunk[0]
if event_type == '\xff':
(num, i) = var_int(chunk[2:])
size = 2 + i + num
data = chunk[size - num:size]
if chunk[1] == 'Q':
tempo = struct.unpack('>I', '\x00' + data)[0]
tempos.append((deltasum, TEMPO, tempo))
chunk = chunk[size:]
continue
if event_type in ('\xf0', '\xf7'):
chunk = chunk[1 + sum(var_int(chunk[1:])):]
continue
event_num = ord(event_type)
if event_num < 128:
offset = -1
event_num = ord(status)
elif event_num >= 240:
break
else:
offset = 0
status = event_type
events.append((deltasum, MIDI, delta))
if event_num >> 4 in (13, 12):
chunk = chunk[2 + offset:]
continue
chunk = chunk[3 + offset:]
return (events, tempos)
def read_midi_length(fileobj):
'''Returns the duration in seconds. Can raise all kind of errors...'''
def read_chunk(fileobj):
info = fileobj.read(8)
chunklen = struct.unpack('>I', info[4:])[0]
return (info[:4], fileobj.read(chunklen))
(identifier, chunk) = read_chunk(fileobj)
if identifier != 'MThd':
raise MidiError('Not a MIDI file')
format_ = struct.unpack('>H', chunk[:2])[0]
if format_ > 1:
raise MidiError('Not supported format %d' % format_)
ntracks = struct.unpack('>H', chunk[2:4])[0]
tickdiv = struct.unpack('>H', chunk[4:6])[0]
if tickdiv >> 15:
raise MidiError('Not supported timing interval')
tracks = []
first_tempos = None
for tracknum in xrange(ntracks):
(identifier, chunk) = read_chunk(fileobj)
if identifier != 'MTrk':
break
(events, tempos) = read_track(chunk)
if not first_tempos:
pass
first_tempos = tempos
if format_ == 1:
tempos = list(first_tempos)
events += tempos
events.sort()
tracks.append(events)
durations = []
for events in tracks:
tempo = 500000
parts = []
deltasum = 0
for dummy, type_, data in events:
if type_ == TEMPO:
parts.append((deltasum, tempo))
tempo = data
deltasum = 0
continue
deltasum += data
parts.append((deltasum, tempo))
duration = 0
for deltasum, tempo in parts:
quarter = deltasum / float(tickdiv)
tpq = tempo
duration += quarter * tpq
duration /= 1000000
durations.append(duration)
return max(durations)